package club.mrxiao.gps.task;

import club.mrxiao.gps.common.constant.GpsCacheKeyConstant;
import club.mrxiao.gps.common.utils.JdbcUtil;
import club.mrxiao.gps.domain.TGpsData;
import club.mrxiao.gps.exception.RedisConnectException;
import club.mrxiao.gps.service.RedisService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Set;

/**
 * 坐标保存
 *
 * @author zhaolei
 */
@Slf4j
@Component
public class PointDateBaseTask {

    private static final int BATCH_COUNT = 1;

    private List<TGpsData> cachedDataList = Lists.newArrayListWithExpectedSize(BATCH_COUNT);

    private final RedisService redisService;

    @Autowired
    public PointDateBaseTask(RedisService redisService) {
        this.redisService = redisService;
    }

    public void run() {

        try {
            log.info("读取轨迹点数据");
            Set<String> list = this.redisService.zrange(GpsCacheKeyConstant.GPS_DATA_LIST, 0, 100);

            for (String pointStr : list) {
                JSONObject json = JSONObject.parseObject(pointStr);
                TGpsData point = JSON.toJavaObject(json, TGpsData.class);
                cachedDataList.add(point);
                redisService.zrem(GpsCacheKeyConstant.GPS_DATA_LIST, pointStr);
            }
        } catch (RedisConnectException redisConnectException) {
            redisConnectException.printStackTrace();
        }

        if (cachedDataList.size() >= BATCH_COUNT) {
            saveData();
            cachedDataList = Lists.newArrayListWithExpectedSize(BATCH_COUNT);
        }
    }

    /**
     * 加上存储数据库
     */
    private void saveData() {
        log.info("{}条数据，开始存储数据库！", cachedDataList.size());
        Long begin = System.currentTimeMillis();

        // 获取jdbc连接
        Connection conn = JdbcUtil.getConnection();

        try {
            // 获取系统时间
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            String time = LocalDateTime.now().format(formatter);

            StringBuffer suffix = new StringBuffer();
            // 设置事务为非自动提交
            conn.setAutoCommit(false);
            PreparedStatement pst = conn.prepareStatement("select 1");
            // 构建sql前缀
            String prefix = "insert into `t_gps_data`(`id`,`imei`,`gps_state`,`latitude`,`longitude`,`create_time`) values ";
            // 外层循环，总提交事务次数
            for (TGpsData gpsDataInputDTO : cachedDataList) {
                // 构建sql后缀
                suffix.append("(" + null + ",")
                        .append(gpsDataInputDTO.getImei() + ",")
                        .append(gpsDataInputDTO.getGpsState() + ",")
                        .append(gpsDataInputDTO.getLatitude() + ",")
                        .append(gpsDataInputDTO.getLongitude() + ",")
                        .append("\"" + time + "\"" + "),");
            }
            // 构建完整sql
            String sql = prefix + (suffix.substring(0, suffix.length() - 1));
            pst.addBatch(sql); // 添加执行sql
            pst.executeBatch();  // 执行操作
            conn.commit();     // 提交事务
            suffix.setLength(0);  // 清空上一次添加的数据
            // 头等连接
            pst.close();
        } catch (SQLException e) {
            log.error("存储数据库错误!" + e);
            e.printStackTrace();
        } finally {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        // 结束时间
        Long end = System.currentTimeMillis();
        log.info("耗时 time : " + (end - begin) / 1000 + " s");
    }
}
